<template>
  <div class="pictures-content">
    <!-- 添加标签页导航 -->
    <div class="fixed-header">
      <a-tabs v-model:activeKey="activeTabKey" class="picture-tabs">
        <a-tab-pane key="my-pictures" tab="我的图片"></a-tab-pane>
        <a-tab-pane key="rejected" tab="被拒绝"></a-tab-pane>
        <a-tab-pane key="pending" tab="待审核"></a-tab-pane>
        <a-tab-pane key="ai-pictures" tab="AI图片">
          <template #tab>
            <a-tooltip placement="top">
              <template #title>
                <div>图片要求：</div>
                <div>• 文件大小：500KB - 5MB</div>
                <div>• 分辨率要求：</div>
                <div>- 最小：建议300x300像素以上</div>
                <div>- 最大：单边不超过10000像素</div>
              </template>
              AI图片
              <QuestionCircleOutlined style="margin-left: 4px" />
            </a-tooltip>
          </template>
        </a-tab-pane>
        <a-tab-pane key="ai-tasks" tab="AI任务">
          <template #tab>
            <a-tooltip placement="top">
              <template #title>
                <div>图片要求：</div>
                <div>• 文件大小：500KB - 5MB</div>
                <div>• 分辨率要求：</div>
                <div>- 最小：建议300x300像素以上</div>
                <div>- 最大：单边不超过10000像素</div>
                <div>注：不满足部分要求可能扩图失败！</div>
              </template>
              AI任务
              <QuestionCircleOutlined style="margin-left: 4px" />
            </a-tooltip>
          </template>
        </a-tab-pane>
      </a-tabs>
      <div class="pictures-header">
        <div class="filter-section">
          <div class="left-filters">
            <a-select
              v-if="['my-pictures', 'rejected', 'pending'].includes(activeTabKey)"
              v-model:value="queryParams.category"
              placeholder="请选择分类"
              style="width: 200px"
              allowClear
            >
              <a-select-option v-for="category in categories" :key="category" :value="category">
                {{ category }}
              </a-select-option>
            </a-select>
            <a-select
              v-if="['my-pictures', 'rejected', 'pending'].includes(activeTabKey)"
              v-model:value="selectedTags"
              mode="multiple"
              placeholder="请选择标签"
              style="width: 300px"
              allowClear
              @change="handleTagsChange"
            >
              <a-select-option v-for="tag in tags" :key="tag" :value="tag">
                {{ tag }}
              </a-select-option>
            </a-select>
            <a-input-search
              v-model:value="queryParams.description"
              :placeholder="
                ['ai-pictures', 'ai-tasks'].includes(activeTabKey) ? '搜索提示词...' : '搜索图片...'
              "
              style="width: 200px"
              @search="handleSearch"
            />
            <div
              class="batch-ops-bar"
              style="display: flex; align-items: center; gap: 12px; margin-left: 16px"
            >
              <a-button @click="toggleSelectAllOnPage">
                {{
                  selectedImages.length === imageList.length && imageList.length > 0
                    ? '取消全选'
                    : '全选本页'
                }}
              </a-button>
              <template v-if="selectedImages.length === imageList.length && imageList.length > 0">
                <a-button type="primary" danger @click="handleBatchDelete">
                  <template #icon><DeleteOutlined /></template>
                  批量删除
                </a-button>
                <a-button @click="clearSelection">
                  <template #icon><CloseOutlined /></template>
                  取消选择
                </a-button>
                <span>已选 {{ selectedImages.length }} 项</span>
              </template>
            </div>
          </div>
          <div class="right-operations">
            <template v-if="activeTabKey === 'ai-tasks' && selectedImages.length > 0">
              <span class="selected-count">已选择 {{ selectedImages.length }} 项</span>
              <a-button type="primary" danger @click="handleBatchDelete">
                <template #icon><DeleteOutlined /></template>
                批量删除
              </a-button>
              <a-button @click="clearSelection">
                <template #icon><CloseOutlined /></template>
                取消选择
              </a-button>
            </template>
            <a-tooltip
              v-if="['ai-pictures', 'ai-tasks'].includes(activeTabKey)"
              placement="bottomRight"
              :overlayStyle="{ maxWidth: '400px' }"
            >
              <template #title>
                <div style="text-align: left">
                  <div style="font-weight: 500; margin-bottom: 8px">图片要求：</div>
                  <div>• 文件大小：500KB - 5MB</div>
                  <div>• 分辨率要求：</div>
                  <div style="padding-left: 12px">- 最小：建议300x300像素以上</div>
                  <div style="padding-left: 12px">- 最大：单边不超过10000像素</div>
                  <div style="color: #ff4d4f; margin-top: 8px">
                    注：不满足部分要求可能扩图失败！
                  </div>
                </div>
              </template>
              <a-button>
                <template #icon><InfoCircleOutlined /></template>
                图片要求
              </a-button>
            </a-tooltip>
            <a-button type="primary" @click="fetchImageList">
              <template #icon><ReloadOutlined /></template>
              刷新
            </a-button>
            <a-button @click="handleReset">
              <template #icon><UndoOutlined /></template>
              重置
            </a-button>
          </div>
        </div>
      </div>
    </div>

    <div class="content-wrapper">
      <a-spin :spinning="loading">
        <!-- 根据不同标签页显示不同内容 -->
        <template v-if="imageList.length > 0">
          <div class="image-grid">
            <div
              v-for="image in imageList"
              :key="image.id"
              class="image-item"
              :class="{ selected: selectedImages.includes(image.id) }"
              @click="handleImageClick(image)"
            >
              <div class="image-wrapper">
                <img
                  :src="
                    ['ai-pictures', 'ai-tasks'].includes(activeTabKey)
                      ? IMAGE_PREFIX + (image.aiUrl ? image.aiUrl : image.sourceUrl || '')
                      : IMAGE_PREFIX + (image.thumbnailUrl || image.url || '')
                  "
                  :alt="image.name || image.picName"
                  class="image-preview"
                />
                <div v-if="activeTabKey === 'rejected'" class="review-status status-rejected">
                  被驳回
                </div>
                <div v-if="activeTabKey === 'pending'" class="review-status status-pending">
                  待审核
                </div>
                <div
                  v-if="activeTabKey === 'ai-tasks'"
                  class="task-status-badge" :class="[
                    {
                      'status-pending': image.taskStatus === 'PENDING',
                      'status-running': image.taskStatus === 'RUNNING',
                      'status-success': image.taskStatus === 'SUCCESS',
                      'status-failed': image.taskStatus === 'FAILED',
                    },
                  ]"
                >
                  {{ getTaskStatusText(image.taskStatus) }}
                </div>
                <div class="image-overlay">
                  <a-space>
                    <template v-if="activeTabKey === 'ai-tasks'">
                      <a-button type="primary" shape="circle" @click.stop="showTaskDetail(image)">
                        <template #icon><EyeOutlined /></template>
                      </a-button>
                      <a-button
                        type="primary"
                        danger
                        shape="circle"
                        @click.stop="handleDelete(image)"
                      >
                        <template #icon><DeleteOutlined /></template>
                      </a-button>
                    </template>
                    <template v-else>
                      <a-button
                        v-if="!['ai-tasks', 'ai-pictures'].includes(activeTabKey)"
                        type="primary"
                        shape="circle"
                        @click.stop="handleEdit(image)"
                      >
                        <template #icon><EditOutlined /></template>
                      </a-button>
                      <a-button type="primary" shape="circle" @click.stop="handleDownload(image)">
                        <template #icon><DownloadOutlined /></template>
                      </a-button>
                      <a-button
                        type="primary"
                        danger
                        shape="circle"
                        @click.stop="handleDelete(image)"
                      >
                        <template #icon><DeleteOutlined /></template>
                      </a-button>
                    </template>
                  </a-space>
                </div>
              </div>
              <div class="image-info">
                <div class="image-name">{{ image.name || image.picName }}</div>
                <div v-if="activeTabKey === 'ai-pictures'" class="ai-image-info">
                  <div class="image-actions">
                    <a-button type="primary" size="small" @click.stop="handleDownload(image)">
                      <template #icon><DownloadOutlined /></template>
                      下载
                    </a-button>
                  </div>
                </div>
              </div>
            </div>
          </div>

          <!-- 分页 -->
          <div class="pagination-bar">
            <a-pagination
              v-model:current="queryParams.page"
              :total="total"
              :pageSize="queryParams.pageSize"
              showSizeChanger
              showQuickJumper
              :showTotal="t => `共 ${t} 张图片`"
              @change="handlePageChange"
            />
          </div>
        </template>

        <template v-else>
          <a-empty description="暂无数据" />
        </template>
      </a-spin>
    </div>

    <!-- 图片预览弹窗 -->
    <a-modal
      v-model:visible="detailVisible"
      :footer="null"
      width="1200px"
      :style="{
        maxWidth: '90vw',
        height: '80vh',
        top: '10vh',
      }"
      @cancel="handleDetailClose"
      wrapClassName="image-preview-modal"
    >
      <div class="image-detail" v-if="currentImage">
        <div class="detail-content">
          <!-- 左侧图片展示 -->
          <div class="detail-image">
            <img :src="IMAGE_PREFIX + currentImage.thumbnailUrl" :alt="currentImage.introduction" />
          </div>

          <!-- 右侧信息展示 -->
          <div class="detail-info">
            <h3 class="preview-title">图片信息</h3>
            <div class="info-item">
              <span class="info-label">文件名：</span>
              <span class="info-value">{{ currentImage.name }}</span>
            </div>
            <div class="info-item">
              <span class="info-label">描述：</span>
              <span class="info-value" :class="{ 'empty-text': !currentImage.introduction }">
                {{ currentImage.introduction || '暂无描述' }}
              </span>
            </div>
            <div class="info-item">
              <span class="info-label">分类：</span>
              <a-tag v-if="currentImage.category" class="info-tag">{{ currentImage.category }}</a-tag>
              <span v-else class="empty-text">未分类</span>
            </div>
            <div class="info-item">
              <span class="info-label">标签：</span>
              <div class="info-value">
                <template v-if="currentImage.tags && currentImage.tags.length">
                  <div class="tags-list">
                    <template v-for="(tag, index) in currentImage.tags" :key="tag">
                      <template v-if="index < 4">
                        <a-tag class="info-tag">{{ tag }}</a-tag>
                      </template>
                    </template>
                    <a-tooltip
                      v-if="currentImage.tags.length > 4"
                      :title="currentImage.tags.slice(4).join(', ')"
                    >
                      <a-tag class="info-tag"> +{{ currentImage.tags.length - 4 }} </a-tag>
                    </a-tooltip>
                  </div>
                </template>
                <span v-else class="empty-text">暂无标签</span>
              </div>
            </div>
            <div class="info-item">
              <span class="info-label">大小：</span>
              <span class="info-value">{{ formatSize(Number(currentImage.picSize)) }}</span>
            </div>
            <div class="info-item">
              <span class="info-label">分辨率：</span>
              <span class="info-value">{{ currentImage.picWidth }} × {{ currentImage.picHeight }}</span>
            </div>
            <div class="info-item">
              <span class="info-label">比例：</span>
              <span class="info-value">{{ currentImage.picScale?.toFixed(2) || '-' }}</span>
            </div>
            <div class="info-item">
              <span class="info-label">格式：</span>
              <span class="info-value">{{ currentImage.picFormat?.toUpperCase() || '-' }}</span>
            </div>
            <div class="info-item">
              <span class="info-label">创建时间：</span>
              <span class="info-value" :class="{ 'empty-text': !currentImage.createTime }">
                {{ currentImage.createTime ? formatDate(currentImage.createTime) : '未知' }}
              </span>
            </div>
            <div class="info-item">
              <span class="info-label">更新时间：</span>
              <span class="info-value" :class="{ 'empty-text': !currentImage.updateTime }">
                {{ currentImage.updateTime ? formatDate(currentImage.updateTime) : '未知' }}
              </span>
            </div>
            <div class="info-item" v-if="activeTabKey === 'rejected' && currentImage.reviewMessage">
              <span class="info-label reject-label">驳回原因：</span>
              <div class="reject-reason">
                <a-tooltip :title="currentImage.reviewMessage">
                  <span class="reason-text truncated reject-value">
                    {{ currentImage.reviewMessage }}
                  </span>
                </a-tooltip>
              </div>
            </div>
          </div>
        </div>
      </div>
    </a-modal>

    <!-- 编辑弹窗 -->
    <a-modal
      v-model:visible="editVisible"
      title="编辑图片"
      @ok="handleEditSubmit"
      @cancel="handleEditCancel"
      :confirmLoading="editLoading"
      width="1000px"
      okText="确认"
      cancelText="取消"
    >
      <div class="edit-content" v-if="editingImage">
        <!-- 图片编辑器 -->
        <div class="editor-container">
          <div class="image-preview">
            <img
              :src="editingImage?.url"
              :style="{
                transform: `
                  rotate(${rotation}deg) 
                  scale(${flipX ? -1 : 1}, ${flipY ? -1 : 1})
                  scale(${zoom})
                `,
              }"
              ref="imageRef"
            />
          </div>
          <div class="editor-tools">
            <a-space wrap>
              <!-- 旋转工具 -->
              <a-button-group>
                <a-button @click="rotation -= 90">
                  <template #icon><RotateLeftOutlined /></template>
                  向左旋转
                </a-button>
                <a-button @click="rotation += 90">
                  <template #icon><RotateRightOutlined /></template>
                  向右旋转
                </a-button>
              </a-button-group>

              <!-- 翻转工具 -->
              <a-button-group>
                <a-button @click="flipX = !flipX">
                  <template #icon><SwapOutlined /></template>
                  水平翻转
                </a-button>
                <a-button @click="flipY = !flipY">
                  <template #icon><SwapOutlined :rotate="90" /></template>
                  垂直翻转
                </a-button>
              </a-button-group>

              <!-- 缩放工具 -->
              <a-button-group>
                <a-button @click="zoom *= 1.1">
                  <template #icon><ZoomInOutlined /></template>
                  放大
                </a-button>
                <a-button @click="zoom *= 0.9">
                  <template #icon><ZoomOutOutlined /></template>
                  缩小
                </a-button>
              </a-button-group>

              <!-- 重置按钮 -->
              <a-button @click="resetImage" type="primary">
                <template #icon><UndoOutlined /></template>
                重置
              </a-button>
            </a-space>
          </div>
        </div>

        <!-- 表单部分 -->
        <div class="edit-form">
          <a-form :model="editForm" layout="vertical">
            <a-form-item label="描述">
              <a-textarea
                v-model:value="editForm.description"
                placeholder="请输入图片描述"
                :rows="2"
              />
            </a-form-item>
            <a-form-item label="分类">
              <a-select
                v-model:value="editForm.category"
                placeholder="请选择分类"
                style="width: 100%"
                allowClear
              >
                <a-select-option v-for="category in categories" :key="category" :value="category">
                  {{ category }}
                </a-select-option>
              </a-select>
            </a-form-item>
            <a-form-item label="标签">
              <a-select
                v-model:value="editForm.tags"
                mode="multiple"
                placeholder="请选择标签"
                style="width: 100%"
                allowClear
              >
                <a-select-option v-for="tag in tags" :key="tag" :value="tag">
                  {{ tag }}
                </a-select-option>
              </a-select>
            </a-form-item>
          </a-form>
        </div>
      </div>
    </a-modal>

    <!-- 添加AI任务详情弹窗 -->
    <a-modal v-model:visible="taskDetailVisible" title="任务详情" :footer="null" width="800px">
      <div class="task-detail" v-if="currentTask">
        <div class="task-detail-content">
          <div class="task-image">
            <img
              :src="IMAGE_PREFIX + (currentTask.thumbnailUrl || currentTask.url)"
              :alt="currentTask.picName"
            />
          </div>
          <div class="task-info">
            <div class="info-row">
              <span class="label">图片名称：</span>
              <span>{{ currentTask.picName }}</span>
            </div>
            <div class="info-row">
              <span class="label">任务状态：</span>
              <a-tag
                class="status-tag" :class="[
                  {
                    'status-pending': currentTask.taskStatus === 'PENDING',
                    'status-running': currentTask.taskStatus === 'RUNNING',
                    'status-success': currentTask.taskStatus === 'SUCCESS',
                    'status-failed': currentTask.taskStatus === 'FAILED',
                  },
                ]"
              >
                {{ getTaskStatusText(currentTask.taskStatus) }}
              </a-tag>
            </div>
            <div class="info-row" v-if="currentTask.taskStatus === 'FAILED'">
              <span class="label">失败原因：</span>
              <span class="error-message">{{ getErrorMessage(currentTask.message) }}</span>
            </div>
            <div class="info-row">
              <span class="label">创建时间：</span>
              <span>{{
                currentTask.createTime ? formatDate(currentTask.createTime) : '未知'
              }}</span>
            </div>
          </div>
        </div>
      </div>
    </a-modal>
  </div>
</template>

<script setup lang="ts">
  import { ref, reactive, computed, onMounted, watch } from 'vue'
  import { message } from 'ant-design-vue'
  import { IMAGE_PREFIX } from '@/config/constants'
  import {
    ReloadOutlined,
    UndoOutlined,
    EditOutlined,
    EyeOutlined,
    RotateLeftOutlined,
    RotateRightOutlined,
    ZoomInOutlined,
    ZoomOutOutlined,
    SwapOutlined,
    DownloadOutlined,
    DeleteOutlined,
    CloseOutlined,
    QuestionCircleOutlined,
    InfoCircleOutlined,
  } from '@ant-design/icons-vue'
  import {
    getCategoriesUsingGet1,
    getTagsUsingGet1,
    getPictureListUsingGet1,
    editPictureUsingPost1,
    getAIPicturesUsingGet,
    getAITasksUsingGet,
    batchDeletePicturesUsingDelete1,
  } from '@/api/tupianguanlijiekou'
  import { getSpacePictureListUsingGet1 } from '@/api/gerenkongjianmokuai'
  import { formatDate } from '@/utils/date'

  // 状态变量
  const activeTabKey = ref('my-pictures')
  const imageList = ref<any[]>([])
  const total = ref(0)
  const loading = ref(false)

  // 查询参数
  interface QueryParams {
    page: number
    pageSize: number
    category: string | undefined
    tags: string
    description: string
    taskStatus: string | undefined
    reviewStatus: 0 | 2 | undefined
  }
  const queryParams = reactive<QueryParams>({
    page: 1,
    pageSize: 30,
    category: undefined,
    tags: '',
    description: '',
    taskStatus: undefined,
    reviewStatus: undefined,
  })

  // 分类和标签
  const categories = ref<string[]>([])
  const tags = ref<string[]>([])

  // 详情相关
  const detailVisible = ref<boolean>(false)
  const currentImage = ref<any>(null)
  const showFullReason = ref(false)

  // 编辑相关
  const editVisible = ref(false)
  const editLoading = ref(false)
  const editingImage = ref<any>(null)
  const hasImageChanged = ref(false)
  const rotation = ref(0)
  const flipX = ref(false)
  const flipY = ref(false)
  const zoom = ref(1)
  const imageRef = ref<HTMLImageElement | null>(null)

  const editForm = reactive({
    description: '',
    category: undefined,
    tags: [] as string[],
  })

  // 选中的标签数组
  const selectedTags = computed({
    get: () => (queryParams.tags ? queryParams.tags.split(',').filter(Boolean) : []),
    set: val => {
      queryParams.tags = val.join(',')
    },
  })

  // 选中的图片id数组，类型为 number[]
  const selectedImages = ref<number[]>([])

  // 清除选择
  const clearSelection = () => {
    selectedImages.value = []
  }
  // 处理单个删除
  const handleDelete = async (image: any) => {
    try {
      const params: any = { pictureIds: [image.id] }
      if (['ai-pictures', 'ai-tasks'].includes(activeTabKey.value)) {
        params.type = 'ai'
      }
      await batchDeletePicturesUsingDelete1(params)
      message.success('删除成功')
      selectedImages.value = selectedImages.value.filter(id => id !== image.id)
      await fetchImageList()
    } catch {
      message.error('删除失败')
    }
  }

  // 处理批量删除
  const handleBatchDelete = async () => {
    if (!selectedImages.value.length) {
      message.warning('请选择要删除的图片')
      return
    }
    try {
      const params: any = { pictureIds: selectedImages.value }
      if (['ai-pictures', 'ai-tasks'].includes(activeTabKey.value)) {
        params.type = 'ai'
      }
      await batchDeletePicturesUsingDelete1(params)
      message.success('批量删除成功')
      clearSelection()
      await fetchImageList()
    } catch {
      message.error('批量删除失败')
    }
  }

  // 处理单个图片下载
  const handleDownload = async (image: any) => {
    try {
      const downloadUrl =
        activeTabKey.value === 'ai-pictures'
          ? image.url
          : `/api/picture/download?url=${encodeURIComponent(image.url)}`

      const response = await fetch(downloadUrl)
      if (!response.ok) throw new Error('下载失败')

      const blob = await response.blob()
      const url = window.URL.createObjectURL(blob)
      const a = document.createElement('a')
      a.href = url
      a.download = image.name || `AI图片_${image.id}.jpg`
      document.body.appendChild(a)
      a.click()
      window.URL.revokeObjectURL(url)
      document.body.removeChild(a)

      message.success('下载成功')
    } catch (error) {
      console.error('下载失败:', error)
      message.error('下载失败')
    }
  }

  // 格式化文件大小
  const formatSize = (bytes: number) => {
    if (bytes === 0) return '0 B'
    const k = 1024
    const sizes = ['B', 'KB', 'MB', 'GB', 'TB']
    const i = Math.floor(Math.log(bytes) / Math.log(k))
    return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
  }

  // 处理标签变化
  const handleTagsChange = (value: string[]) => {
    queryParams.tags = value.join(',')
  }

  // 获取分类列表
  const fetchCategories = async () => {
    try {
      const res = await getCategoriesUsingGet1()
      if (res.data.code === 200 && Array.isArray(res.data.data)) {
        categories.value = res.data.data
      } else {
        categories.value = []
      }
    } catch {
      message.error('获取分类列表失败')
    }
  }

  // 获取标签列表
  const fetchTags = async () => {
    try {
      const res = await getTagsUsingGet1()
      if (res.data.code === 200 && Array.isArray(res.data.data)) {
        tags.value = res.data.data
      } else {
        tags.value = []
      }
    } catch {
      message.error('获取标签列表失败')
    }
  }

  // 获取图片列表
  const fetchImageList = async () => {
    loading.value = true
    try {
      let res

      switch (activeTabKey.value) {
        case 'my-pictures':
          res = await getPictureListUsingGet1({
            page: queryParams.page,
            pageSize: queryParams.pageSize,
            tags: queryParams.tags,
            description: queryParams.description,
            category: queryParams.category,
            type: 'self',
          })
          break

        case 'rejected':
          res = await getSpacePictureListUsingGet1({
            page: queryParams.page,
            pageSize: queryParams.pageSize,
            tags: queryParams.tags,
            description: queryParams.description,
            category: queryParams.category,
            reviewStatus: 2,
          })
          break

        case 'pending':
          res = await getSpacePictureListUsingGet1({
            page: queryParams.page,
            pageSize: queryParams.pageSize,
            tags: queryParams.tags,
            description: queryParams.description,
            category: queryParams.category,
            reviewStatus: 0,
          })
          break

        case 'ai-pictures':
          res = await getAIPicturesUsingGet({
            page: queryParams.page,
            pageSize: queryParams.pageSize,
            prompt: queryParams.description,
          })
          if (res?.data?.code === 200) {
            imageList.value = res.data.data?.list || []
            total.value = Number(res.data.data?.total || 0)
          }
          break

        case 'ai-tasks':
          res = await getAITasksUsingGet({
            page: queryParams.page,
            pageSize: queryParams.pageSize,
            status: queryParams.taskStatus,
          })
          break
      }

      if (res?.data?.code === 200) {
        imageList.value = res.data.data?.records || []
        total.value = Number(res.data.data?.total || 0)
      } else {
        message.error('获取列表失败')
      }
    } catch (error) {
      console.error('获取列表失败:', error)
      message.error('获取列表失败')
    } finally {
      loading.value = false
    }
  }

  // 监听标签页切换
  watch(
    () => activeTabKey.value,
    () => {
      queryParams.page = 1
      queryParams.pageSize = 30
      fetchImageList()
    }
  )

  // 处理页码变化
  const handlePageChange = (page: number, pageSize?: number) => {
    queryParams.page = page
    queryParams.pageSize = pageSize || 30
    fetchImageList()
  }

  // 处理搜索
  const handleSearch = () => {
    queryParams.page = 1
    fetchImageList()
  }

  // 重置筛选条件
  const handleReset = () => {
    // 重置通用参数
    queryParams.description = ''
    queryParams.page = 1
    queryParams.pageSize = 30

    // 根据不同标签页重置特定参数
    if (['my-pictures'].includes(activeTabKey.value)) {
      queryParams.category = undefined
      queryParams.tags = ''
    } else if (activeTabKey.value === 'rejected') {
      queryParams.reviewStatus = 2
    } else if (activeTabKey.value === 'pending') {
      queryParams.reviewStatus = 0
    } else if (activeTabKey.value === 'ai-tasks') {
      queryParams.taskStatus = undefined
    }

    fetchImageList()
  }

  // 处理图片点击
  const handleImageClick = image => {
    // 处理 tags 字段的兼容性
    const processedImage = {
      ...image,
      tags: Array.isArray(image.tags)
        ? image.tags
        : typeof image.tags === 'string'
          ? JSON.parse(image.tags)
          : image.tagsList || [],
    }
    currentImage.value = processedImage
    detailVisible.value = true
  }

  // 处理详情关闭
  const handleDetailClose = () => {
    currentImage.value = null
    detailVisible.value = false
    showFullReason.value = false
  }

  // 处理编辑按钮点击
  const handleEdit = async (image: any) => {
    try {
      const imgUrl = IMAGE_PREFIX + image.url
      const response = await fetch(`/api/picture/download?url=${encodeURIComponent(imgUrl)}`, {
        method: 'GET',
        credentials: 'include',
      })

      if (!response.ok) {
        throw new Error('下载图片失败')
      }

      const blob = await response.blob()
      const localUrl = URL.createObjectURL(blob)

      editingImage.value = {
        ...image,
        url: localUrl,
        originalUrl: imgUrl,
      }
      editForm.description = image.introduction || ''
      editForm.category = image.category
      editForm.tags = image.tags || []
      editVisible.value = true
      hasImageChanged.value = false
    } catch (error) {
      console.error('加载图片失败:', error)
      message.error('加载图片失败')
    }
  }

  // 重置图片
  const resetImage = () => {
    rotation.value = 0
    flipX.value = false
    flipY.value = false
    zoom.value = 1
    hasImageChanged.value = false
  }

  // 处理编辑取消
  const handleEditCancel = () => {
    if (editingImage.value?.url) {
      URL.revokeObjectURL(editingImage.value.url)
    }
    editVisible.value = false
    editingImage.value = null
    hasImageChanged.value = false
  }

  // 处理编辑提交
  const handleEditSubmit = async () => {
    if (!editingImage.value) return

    editLoading.value = true
    try {
      const params = {
        pictureId: editingImage.value.id,
      }

      let file: File | undefined

      // 如果图片被编辑过(做了旋转、缩放等操作),生成新的文件
      if (hasImageChanged.value && imageRef.value) {
        const canvas = document.createElement('canvas')
        const ctx = canvas.getContext('2d')
        const img = imageRef.value

        // 设置canvas尺寸为原图尺寸
        canvas.width = img.naturalWidth
        canvas.height = img.naturalHeight

        if (ctx) {
          // 应用变换
          ctx.translate(canvas.width / 2, canvas.height / 2)
          ctx.rotate((rotation.value * Math.PI) / 180)
          ctx.scale(flipX.value ? -1 : 1, flipY.value ? -1 : 1)
          ctx.scale(zoom.value, zoom.value)
          ctx.translate(-canvas.width / 2, -canvas.height / 2)

          ctx.drawImage(img, 0, 0)

          // 将canvas转换为Blob
          const blob = await new Promise<Blob>(resolve => {
            canvas.toBlob(b => resolve(b as Blob), 'image/png', 1)
          })
          file = new File([blob], editingImage.value.name || 'edited.png', { type: 'image/png' })
        }
      } else {
        // 如果图片没有被编辑,获取原始图片文件
        try {
          const response = await fetch(editingImage.value.originalUrl)
          const blob = await response.blob()
          file = new File([blob], editingImage.value.name || 'original.png', { type: blob.type })
        } catch (error) {
          console.error('获取原始图片失败:', error)
          message.error('获取原始图片失败')
          return
        }
      }

      // 调用编辑接口,传递所有必需的参数
      const res = await editPictureUsingPost1(
        params,
        file, // 传递文件
        editForm.tags?.length > 0 ? editForm.tags.join(',') : undefined,
        editForm.category,
        editForm.description
      )

      if (res.data.code === 200) {
        message.success('编辑成功')
        if (editingImage.value?.url) {
          URL.revokeObjectURL(editingImage.value.url)
        }
        editVisible.value = false
        fetchImageList()
      } else {
        message.error(res.data.message || '编辑失败')
      }
    } catch (error) {
      console.error('编辑失败:', error)
      message.error('编辑失败')
    } finally {
      editLoading.value = false
    }
  }

  // 初始化
  onMounted(async () => {
    try {
      // 首次加载时获取标签和分类
      await Promise.all([fetchCategories(), fetchTags()])
      // 获取完标签和分类后再获取图片列表
      await fetchImageList()
    } catch (error) {
      console.error('初始化失败:', error)
      message.error('初始化失败')
    }
  })

  // 任务详情相关
  const taskDetailVisible = ref(false)
  const currentTask = ref<any>(null)

  // 显示任务详情
  const showTaskDetail = (task: any) => {
    currentTask.value = task
    taskDetailVisible.value = true
  }

  // 获取任务状态文本
  const getTaskStatusText = (status: string) => {
    const statusMap = {
      PENDING: '等待中',
      RUNNING: '处理中',
      SUCCESS: '已完成',
      FAILED: '已失败',
    }
    return statusMap[status] || '未知状态'
  }

  // 获取错误信息
  const getErrorMessage = (message: string) => {
    const errorMap = {
      // 图片尺寸相关错误
      'the size of input image is too small or to large':
        '图片尺寸或大小不符合要求，细节请看列表页面！',
      'image size is too small': '图片尺寸过小（建议300x300像素以上）',
      'image size is too large': '图片尺寸过大（单边不超过10000像素）',
      'image resolution exceeds limit': '图片分辨率超出限制（单边不超过10000像素）',

      // 图片文件大小相关错误
      'file size exceeds limit': '文件大小超出限制（500KB - 5MB）',
      'file is too small': '文件大小过小（最小500KB）',
      'file is too large': '文件大小过大（最大5MB）',

      // 图片格式相关错误
      'unsupported image format': '不支持的图片格式（支持jpg、png、webp等）',
      'invalid image format': '无效的图片格式',
      'image is corrupted': '图片文件已损坏',

      // 处理过程相关错误
      'processing failed': '图片处理失败，请重试',
      'network error': '网络错误，请检查网络连接',
      'server error': '服务器错误，请稍后重试',
      timeout: '处理超时，请重试',
      // AI处理相关错误
      'ai service unavailable': 'AI服务暂时不可用，请稍后重试',
      'ai processing error': 'AI处理出错，请重试',
      'model loading failed': 'AI模型加载失败，请重试',

      // 权限相关错误
      'permission denied': '没有操作权限',
      unauthorized: '未授权的操作',
      'quota exceeded': '已超出使用配额',

      // 其他错误
      'unknown error': '未知错误',
    }

    // 如果找不到具体的错误映射，尝试进行模糊匹配
    if (!errorMap[message]) {
      if (message.includes('size')) {
        if (message.includes('small')) {
          return '图片尺寸过小，请上传更大的图片（建议300x300像素以上）'
        }
        if (message.includes('large')) {
          return '图片尺寸过大，请压缩后重试（单边不超过10000像素）'
        }
        return '图片尺寸不符合要求，请检查后重试'
      }

      if (message.includes('format')) {
        return '图片格式不支持，请使用常见图片格式（jpg、png、webp等）'
      }

      if (message.includes('network') || message.includes('connection')) {
        return '网络连接异常，请检查网络后重试'
      }

      if (message.includes('server')) {
        return '服务器处理异常，请稍后重试'
      }
    }

    // 返回映射的错误信息，如果没有找到对应的映射，则返回原始消息或默认提示
    return errorMap[message] || message || '处理失败，请检查图片是否符合要求后重试'
  }

  // 全选/取消全选
  const toggleSelectAllOnPage = () => {
    if (selectedImages.value.length === imageList.value.length && imageList.value.length > 0) {
      selectedImages.value = []
    } else {
      selectedImages.value = imageList.value.map((img: any) => img.id)
    }
  }
</script>

<style scoped>
  .pictures-content {
    display: flex;
    flex-direction: column;
    height: calc(100vh - 88px);
    background: var(--theme-surface);
    border-radius: 8px;
    position: relative;
    box-shadow: 0 2px 8px var(--theme-shadow);
    transition: all 0.3s ease;
  }

  /* 固定区域样式 */
  .fixed-header {
    position: sticky;
    top: 0;
    z-index: 10;
    background: var(--theme-surface);
    border-bottom: 1px solid var(--theme-border);
    box-shadow: 0 2px 4px var(--theme-shadow);
    transition: all 0.3s ease;
  }

  .picture-tabs {
    padding: 16px 24px 0;
    :deep(.ant-tabs-nav) {
      margin-bottom: 0;
    }
    :deep(.ant-tabs-tab) {
      padding: 12px 24px;
      font-size: 15px;
      transition: all 0.3s;

      &:hover {
        color: #1890ff;
      }
    }
    :deep(.ant-tabs-tab-active) {
      font-weight: 500;
    }
  }

  .pictures-header {
    padding: 20px 24px;
    background: linear-gradient(to bottom, var(--theme-surface), var(--theme-background));
    transition: all 0.3s ease;
  }

  .filter-section {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 16px;

    .left-filters {
      display: flex;
      gap: 16px;
      align-items: center;
      flex-wrap: wrap;
    }

    .right-operations {
      display: flex;
      gap: 16px;
      align-items: center;

      .selected-count {
        color: #666;
        margin-right: 8px;
      }
    }

    :deep(.ant-select),
    :deep(.ant-input-search) {
      border-radius: 6px;

      &:hover {
        border-color: #40a9ff;
      }
    }

    :deep(.ant-btn) {
      border-radius: 6px;
      height: 32px;
      display: flex;
      align-items: center;
      gap: 4px;

      &:hover {
        transform: translateY(-1px);
        box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
      }
    }
  }

  /* 滚动区域样式 */
  .content-wrapper {
    flex: 1;
    overflow-y: auto;
    padding: 24px;
    height: calc(100vh - 200px);
    background: var(--theme-background);
    transition: all 0.3s ease;
  }

  .image-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: 20px;
    margin-bottom: 24px;
    padding: 0 16px;
  }

  .image-item {
    border: 1px solid var(--theme-border);
    border-radius: 8px;
    overflow: hidden;
    transition: all 0.3s;
    background: var(--theme-surface);
    cursor: pointer;
    position: relative;

    &.selected {
      border-color: var(--theme-primary);
      box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
    }

    &:hover {
      box-shadow: 0 4px 12px var(--theme-shadow);
      transform: translateY(-2px);

      .image-overlay {
        opacity: 1;
      }
    }
  }

  .image-wrapper {
    position: relative;
    width: 100%;
    height: 200px;
    overflow: hidden;

    .image-preview {
      width: 100%;
      height: 100%;
      object-fit: cover;
      transition: transform 0.3s;
    }

    .image-overlay {
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      background: rgba(0, 0, 0, 0.5);
      display: flex;
      justify-content: center;
      align-items: center;
      opacity: 0;
      transition: opacity 0.3s;

      .ant-btn {
        margin: 0 4px;
        background: rgba(255, 255, 255, 0.9);
        border: none;

        &:hover {
          background: #fff;
          transform: scale(1.1);
        }
      }
    }
  }

  .image-info {
    padding: 12px;

    .image-name {
      font-size: 14px;
      color: var(--theme-text);
      margin-bottom: 8px;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
      transition: color 0.3s ease;
    }

    .image-meta {
      margin-bottom: 8px;
      display: flex;
      flex-wrap: wrap;
      gap: 4px;

      .ant-tag {
        margin: 0;
        font-size: 12px;
        padding: 0 8px;
        border-radius: 4px;
      }
    }

    .image-status {
      font-size: 12px;
      color: #666;
      margin-bottom: 8px;
    }

    .image-progress {
      margin-top: 8px;
    }
  }

  .pagination-container {
    text-align: center;
    margin-top: 24px;
  }

  /* 图片预览弹窗样式 */
  :deep(.image-preview-modal) {
    .ant-modal {
      height: 80vh;
      padding-bottom: 0;
    }

    .ant-modal-content {
      height: 100%;
      display: flex;
      flex-direction: column;
      border-radius: 12px;
      overflow: hidden;
      background: var(--theme-surface);
      color: var(--theme-text);
      transition: all 0.3s ease;
    }

    .ant-modal-body {
      flex: 1;
      overflow: auto;
      padding: 24px;
      background: var(--theme-surface);
      color: var(--theme-text);
      transition: all 0.3s ease;
    }
  }

  .image-detail {
    height: 100%;
  }

  .detail-content {
    display: flex;
    gap: 32px;
    height: 100%;
  }

  .detail-image {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--theme-background);
    border-radius: 12px;
    overflow: hidden;
    max-height: calc(80vh - 100px);
    box-shadow: 0 4px 12px var(--theme-shadow);
    transition: all 0.3s ease;

    img {
      max-width: 100%;
      max-height: 100%;
      object-fit: contain;
      transition: transform 0.3s ease;
    }
  }

  .detail-info {
    width: 320px;
    flex-shrink: 0;
    overflow-y: auto;
    padding: 20px;
    background: var(--theme-background);
    border-radius: 12px;
    transition: all 0.3s ease;
  }

  /* 预览标题样式 */
  .preview-title {
    font-size: 18px;
    font-weight: 700;
    margin-bottom: 20px;
    color: var(--theme-text);
    transition: all 0.3s ease;
  }

  /* 深色主题下的标题 */
  [data-theme="dark"] .preview-title {
    color: #ff00ff !important; /* 洋红色，在深色主题下醒目 */
    text-shadow: 0 1px 3px rgba(255, 0, 255, 0.5) !important;
  }

  /* 浅色主题下的标题 */
  [data-theme="light"] .preview-title {
    color: #1890ff !important; /* 蓝色，在浅色主题下清晰 */
    text-shadow: none !important;
  }

  .info-item {
    display: flex;
    align-items: flex-start;
    margin-bottom: 16px;
    padding-bottom: 12px;
    border-bottom: 1px dashed var(--theme-border);
    transition: border-color 0.3s ease;

    &:last-child {
      border-bottom: none;
    }
  }

  /* 信息标签样式 */
  .info-label {
    width: 80px;
    flex-shrink: 0;
    font-weight: 600;
    color: var(--theme-textSecondary);
    transition: all 0.3s ease;
  }

  /* 深色主题下的标签 */
  [data-theme="dark"] .info-label {
    color: #00ffff !important; /* 青色，在深色主题下醒目 */
    text-shadow: 0 1px 3px rgba(0, 255, 255, 0.5) !important;
  }

  /* 浅色主题下的标签 */
  [data-theme="light"] .info-label {
    color: #666666 !important; /* 深灰色，在浅色主题下清晰 */
    text-shadow: none !important;
  }

  /* 信息值样式 */
  .info-value {
    flex: 1;
    min-width: 0;
    font-weight: 600;
    color: var(--theme-text);
    transition: all 0.3s ease;
  }

  /* 深色主题下的值 */
  [data-theme="dark"] .info-value {
    color: #ffff00 !important; /* 黄色，在深色主题下醒目 */
    text-shadow: 0 1px 3px rgba(255, 255, 0, 0.5) !important;
  }

  /* 浅色主题下的值 */
  [data-theme="light"] .info-value {
    color: #333333 !important; /* 深黑色，在浅色主题下清晰 */
    text-shadow: none !important;
  }

  /* 驳回标签样式 */
  .reject-label {
    color: #ff4d4f !important; /* 红色 */
    text-shadow: 0 1px 3px rgba(255, 77, 79, 0.5) !important;
  }

  /* 驳回值样式 */
  .reject-value {
    color: #ff4d4f !important; /* 红色 */
    text-shadow: 0 1px 3px rgba(255, 77, 79, 0.5) !important;
  }

  .tags-list {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
  }

  .info-tag {
    margin: 0;
    font-size: 12px;
    padding: 2px 10px;
    border-radius: 12px;
    background: var(--theme-primary);
    border: 1px solid var(--theme-primary);
    color: var(--theme-surface);
    transition: all 0.3s ease;
    font-weight: 500;  /* 加粗字体 */

    &:hover {
      background: var(--theme-secondary);
      border-color: var(--theme-secondary);
      color: var(--theme-surface);
    }
  }

  /* 深色主题下的标签优化 */
  [data-theme="dark"] .info-tag {
    background: #1890ff;  /* 更亮的蓝色 */
    border-color: #1890ff;
    color: #ffffff;
    box-shadow: 0 1px 3px rgba(24, 144, 255, 0.3);  /* 添加阴影 */
  }

  [data-theme="dark"] .info-tag:hover {
    background: #40a9ff;  /* 更亮的悬停色 */
    border-color: #40a9ff;
    color: #ffffff;
    box-shadow: 0 2px 6px rgba(24, 144, 255, 0.4);
  }

  .empty-text {
    color: var(--theme-textSecondary);
    font-style: italic;
    transition: color 0.3s ease;
  }

  /* 编辑器样式 */
  .editor-container {
    margin-bottom: 24px;
  }

  .image-preview {
    width: 100%;
    height: 300px;
    display: flex;
    justify-content: center;
    align-items: center;
    background: #f8f8f8;
    border: 2px dashed #e8e8e8;
    border-radius: 12px;
    overflow: hidden;
    margin-bottom: 20px;
    transition: all 0.3s ease;

    &:hover {
      border-color: #40a9ff;
      box-shadow: 0 2px 8px rgba(24, 144, 255, 0.1);
    }

    img {
      max-width: 400px;
      max-height: 280px;
      object-fit: contain;
      transition: all 0.3s ease;
    }
  }

  .editor-tools {
    padding: 16px;
    background: #f8f8f8;
    border-radius: 8px;

    :deep(.ant-space) {
      width: 100%;
      justify-content: center;
    }

    :deep(.ant-btn) {
      height: 36px;
      padding: 0 16px;
      border-radius: 6px;
      display: flex;
      align-items: center;
      gap: 6px;

      &:hover {
        transform: translateY(-1px);
        box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
      }

      .anticon {
        font-size: 16px;
      }
    }
  }

  .edit-form {
    margin-top: 24px;

    :deep(.ant-form-item-label) {
      font-weight: 500;
    }

    :deep(.ant-input),
    :deep(.ant-select) {
      border-radius: 6px;

      &:hover,
      &:focus {
        border-color: #40a9ff;
        box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.1);
      }
    }
  }

  .task-status {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-top: 8px;

    .status-tag {
      border-radius: 12px;
      padding: 2px 8px;
      font-size: 12px;

      &.status-pending {
        color: #d48806;
        background: #fff7e6;
        border-color: #ffd591;
      }

      &.status-running {
        color: #1890ff;
        background: #e6f7ff;
        border-color: #91d5ff;
      }

      &.status-suspended {
        color: #fa8c16;
        background: #fff7e6;
        border-color: #ffd591;
      }

      &.status-succeeded {
        color: #52c41a;
        background: #f6ffed;
        border-color: #b7eb8f;
      }

      &.status-failed {
        color: #f5222d;
        background: #fff1f0;
        border-color: #ffa39e;
      }
    }

    .create-time {
      font-size: 12px;
      color: #999;
    }
  }

  .task-message {
    font-size: 12px;
    color: #666;
    margin-top: 8px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .select-box {
    position: absolute;
    top: 8px;
    left: 8px;
    z-index: 2;
    background: rgba(255, 255, 255, 0.8);
    padding: 4px;
    border-radius: 4px;

    :deep(.ant-checkbox-wrapper) {
      margin-right: 0;
    }

    :deep(.ant-checkbox-checked .ant-checkbox-inner) {
      background-color: #1890ff;
      border-color: #1890ff;
    }
  }

  .ai-image-info {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-top: 8px;

    .status-tag {
      border-radius: 12px;
      padding: 2px 8px;
      font-size: 12px;

      &.status-succeeded {
        color: #52c41a;
        background: #f6ffed;
        border-color: #b7eb8f;
      }

      &.status-failed {
        color: #f5222d;
        background: #fff1f0;
        border-color: #ffa39e;
      }
    }

    .create-time {
      font-size: 12px;
      color: #999;
    }
  }

  .image-actions {
    margin-top: 12px;
    display: flex;
    justify-content: center;

    .ant-btn {
      border-radius: 16px;
      padding: 0 16px;
      height: 28px;
      font-size: 12px;
      display: flex;
      align-items: center;
      gap: 4px;

      &:hover {
        transform: translateY(-1px);
        box-shadow: 0 2px 6px rgba(24, 144, 255, 0.2);
      }

      .anticon {
        font-size: 14px;
      }
    }
  }

  /* 添加审核状态水印样式 */
  .review-status {
    position: absolute;
    top: 8px;
    right: 8px;
    padding: 4px 8px;
    border-radius: 4px;
    font-size: 12px;
    font-weight: 500;
    z-index: 2;
  }

  .status-pending {
    background: #faad14;
    color: #fff;
  }

  .status-approved {
    background: #52c41a;
    color: #fff;
  }

  .status-rejected {
    background: #ff4d4f;
    color: #fff;
  }

  /* 添加提示信息样式 */
  .requirement-alert {
    margin-bottom: 20px;
    padding: 0 16px;
  }

  .requirement-content {
    font-size: 14px;
  }

  .requirement-title {
    font-weight: 500;
    color: #1890ff;
  }

  .requirement-list {
    margin: 0;
    padding-left: 20px;

    ul {
      padding-left: 20px;
      margin: 4px 0;
    }
  }

  .requirement-note {
    color: #ff4d4f;
    font-weight: 500;
    margin-top: 4px;
  }

  /* 任务状态水印样式 */
  .task-status-badge {
    position: absolute;
    top: 8px;
    right: 8px;
    padding: 4px 8px;
    border-radius: 4px;
    font-size: 12px;
    font-weight: 500;
    z-index: 2;

    &.status-pending {
      background: #faad14;
      color: #fff;
    }

    &.status-running {
      background: #1890ff;
      color: #fff;
    }

    &.status-success {
      background: #52c41a;
      color: #fff;
    }

    &.status-failed {
      background: #ff4d4f;
      color: #fff;
    }
  }

  /* 任务详情样式 */
  .task-detail {
    padding: 20px;

    .task-detail-content {
      display: flex;
      gap: 24px;
    }

    .task-image {
      width: 300px;
      height: 300px;
      border-radius: 8px;
      overflow: hidden;
      background: #f5f5f5;

      img {
        width: 100%;
        height: 100%;
        object-fit: contain;
      }
    }

    .task-info {
      flex: 1;

      .info-row {
        margin-bottom: 16px;

        .label {
          color: #666;
          margin-right: 8px;
          font-weight: 500;
        }

        .error-message {
          color: #ff4d4f;
        }
      }

      .status-tag {
        border-radius: 12px;
        padding: 2px 12px;

        &.status-pending {
          color: #d48806;
          background: #fff7e6;
          border-color: #ffd591;
        }

        &.status-running {
          color: #1890ff;
          background: #e6f7ff;
          border-color: #91d5ff;
        }

        &.status-success {
          color: #52c41a;
          background: #f6ffed;
          border-color: #b7eb8f;
        }

        &.status-failed {
          color: #f5222d;
          background: #fff1f0;
          border-color: #ffa39e;
        }
      }
    }
  }

  /* 驳回原因样式 */
  .reject-reason {
    display: flex;
    align-items: flex-start;
    flex: 1;
    min-width: 0;
  }

  .reason-text {
    flex: 1;
    min-width: 0;
    word-break: break-all;
    line-height: 1.5;

    &.truncated {
      display: -webkit-box;
      -webkit-line-clamp: 2;
      -webkit-box-orient: vertical;
      overflow: hidden;
      text-overflow: ellipsis;
    }
  }
</style>
